use crate::todo::models;
use diesel::r2d2::{self, ConnectionManager};
use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

pub fn first_todo()-> Result<Option<models::Todo>, diesel::result::Error>{
    dotenv().ok();

    let connspec = env::var("DATABASE_URL").expect("DATABASE_URL");
    println!("{}",connspec);
    let manager = ConnectionManager::<SqliteConnection>::new(connspec);
    let pool = r2d2::Pool::builder()
        .build(manager)
        .expect("Failed to create pool.");
    let conn = pool.get().expect("couldn't get db connection from pool");
    use crate::todo::schema::todos::dsl::*;

    let user = todos
        .first::<models::Todo>(&conn)
        // .expect("no");
        .optional()?;//may be none
    // println!("{}",user.name);
    Ok(user)
}
pub fn get_todos(){
    dotenv().ok();

    let connspec = env::var("DATABASE_URL").expect("DATABASE_URL");
    println!("{}",connspec);
    let manager = ConnectionManager::<SqliteConnection>::new(connspec);
    let pool = r2d2::Pool::builder()
        .build(manager)
        .expect("Failed to create pool.");
    let conn = pool.get().expect("couldn't get db connection from pool");
    use crate::todo::schema::todos::dsl::*;

    let results = todos//.filter(completed.eq(true))
        .limit(5)
        .load::<models::Todo>(&conn)
        .expect("error load todos");//may be none
    for post in results {
        println!("{}", post.text);
    }
    // println!("{}",user.name);
    // Ok(r)
}
pub fn creat_todo(){
    dotenv().ok();

    let connspec = env::var("DATABASE_URL").expect("DATABASE_URL");
    println!("{}",connspec);
    let manager = ConnectionManager::<SqliteConnection>::new(connspec);
    let pool = r2d2::Pool::builder()
        .build(manager)
        .expect("Failed to create pool.");
    let conn = pool.get().expect("couldn't get db connection from pool");
    use crate::todo::schema::todos::dsl::*;
    
    let new_post = models::NewTodo {
        text: String::from("hello"),
        completed: false,
    };

    diesel::insert_into(todos)
        .values(&new_post)
        .execute(&conn)
        .expect("Error saving new post");
    // println!("{}",user.name);
    // Ok(r)
}
pub fn delete_todo(){
    dotenv().ok();

    let connspec = env::var("DATABASE_URL").expect("DATABASE_URL");
    println!("{}",connspec);
    let manager = ConnectionManager::<SqliteConnection>::new(connspec);
    let pool = r2d2::Pool::builder()
        .build(manager)
        .expect("Failed to create pool.");
    let conn = pool.get().expect("couldn't get db connection from pool");
    use crate::todo::schema::todos::dsl::*;
    

    let num_deleted = diesel::delete(todos.filter(id.eq(1)))
        .execute(&conn)
        .expect("Error deleting posts");

    println!("Deleted {} posts", num_deleted);
}
pub fn update_todo(){
    dotenv().ok();

    let connspec = env::var("DATABASE_URL").expect("DATABASE_URL");
    println!("{}",connspec);
    let manager = ConnectionManager::<SqliteConnection>::new(connspec);
    let pool = r2d2::Pool::builder()
        .build(manager)
        .expect("Failed to create pool.");
    let conn = pool.get().expect("couldn't get db connection from pool");
    use crate::todo::schema::todos::dsl::*;
    
    let id1:i32=11;
    println!("{}",id1);
    let post = diesel::update(todos.find(id1))
        .set(completed.eq(true))
        .execute(&conn)//get_result::<models::Todo>(&conn)
        .expect(&format!("Unable to find post {}", id1.to_string()));
    println!("updated{}",post);
}
fn test_todo(){
    // creat_todo();
    // get_todos();
    // delete_todo();
    update_todo();
}
pub fn main() {
    test_todo();
}
fn test_usr(){
    let todo=first_todo();
    match todo {
        Ok(v) => {
            println!("ok");
            match v {
                None => {println!("none");},
                Some(quotient) => {
                    println!("result");
                },
            }
        }
        ,
        Err(_) => {},
    }
}
